package x.ovo.wechat.bot.common.http;

import x.ovo.wechat.bot.common.Context;
import x.ovo.wechat.bot.common.entity.*;
import x.ovo.wechat.bot.common.http.session.LoginSession;

import java.io.File;
import java.util.List;

/**
 * 微信API
 *
 * @author ovo, created by 2024/05/01
 */
public interface WechatApi {

    ///////////////// 登录、初始化 /////////////////

    /**
     * 设置上下文
     *
     * @param context 上下文
     */
    void setContext(Context context);

    /**
     * 在成功登录后，获取到相应的登录信息、域名后初始化，将cookie、拦截器添加到请求
     */
    void init();

    /**
     * 登录
     *
     * @param autoLogin 自动登录
     */
    void login(boolean autoLogin);

    /**
     * 推送登录
     *
     * @return {@link String} uuid
     */
    String pushLogin();

    /**
     * 初始化微信
     */
    void initWeChat();

    /**
     * 开启状态通知
     */
    boolean statusNotify(String username);

    /**
     * 获取登录会话
     *
     * @return {@link LoginSession}
     */
    LoginSession getLoginSession();

    /**
     * 注销
     */
    void logout();

    /**
     * 同步心跳检查
     *
     * @return {@link SyncCheckResult}
     */
    SyncCheckResult syncCheck();

    ///////////////// 消息相关 /////////////////

    /**
     * Web 同步拉取新消息
     *
     * @return {@link WebSyncResult}
     */
    WebSyncResult webSync();

    /**
     * 发送文本消息
     *
     * @param toUserName 接收消息的用户名
     * @param content    内容
     * @return boolean
     */
    boolean sendText(String toUserName, String content);

    /**
     * 发送表情符号
     *
     * @param toUserName  接收用户名
     * @param emoticonMd5 表情符号 MD5
     * @return boolean
     */
    boolean sendEmoticon(String toUserName, String emoticonMd5);

    /**
     * 发送图片
     *
     * @param toUserName 接收消息的用户名
     * @param file   文件
     * @return boolean
     */
    boolean sendImage(String toUserName, File file);

    /**
     * 发送视频
     *
     * @param toUserName 接收消息的用户名
     * @param file   文件
     * @return boolean
     */
    boolean sendVideo(String toUserName, File file);

    /**
     * 发送文件
     *
     * @param toUserName 接收消息的用户名
     * @param file   文件
     * @return boolean
     */
    boolean sendFile(String toUserName, File file);

    /**
     * 上传媒体
     *
     * @param toUserName 更改为用户名
     * @param file       文件
     * @return {@link MediaResponse }
     */
    UploadResult uploadMedia(String toUserName, File file);

    /**
     * 获取图片
     *
     * @param mediaId 媒体 ID
     * @return {@link byte[]} 图片的byte数组
     */
    byte[] getImage(Long mediaId);

    /**
     * 获取视频
     *
     * @param mediaId 媒体 ID
     * @return {@link byte[] }
     */
    byte[] getVideo(Long mediaId);

    /**
     * 获取语音
     *
     * @param mediaId 媒体 ID
     * @return {@link byte[] }
     */
    byte[] getVoice(Long mediaId);

    ///////////////// 联系人相关 /////////////////

    /**
     * 获取联系人列表
     *
     * @return {@link List}<{@link Contact}>
     */
    List<Contact> getContactList();

    /**
     * 批量获取联系人列表
     * <p>用于批量获取好友信息，或者批量获取群聊中的成员信息。</p>
     *
     * @param queryList 查询列表
     * @return {@link List}<{@link Contact}>
     */
    List<Contact> batchGetContactList(List<BatchContactQuery> queryList);

    /**
     * 通过ID查找用户
     *
     * @param id id
     * @return {@link Contact}
     */
    Contact getContactById(String id);

    /**
     * 根据备注或昵称查找用户
     *
     * @param name 名字
     * @return {@link Contact}
     */
    Contact getContactByName(String name);

    /**
     * 添加好友验证
     *
     * @param recommend 好友名片信息
     * @return boolean
     */
    boolean verify(Recommend recommend);

    /**
     * 添加好友
     *
     * @param userName 用户名
     * @param content  内容
     * @return boolean
     */
    boolean addFriend(String userName, String content);

    /**
     * 修改联系人备注
     *
     * @param remarkName 备注
     * @param username   用户名
     * @return boolean
     */
    boolean modifyContactRemark(String remarkName, String username);

    ///////////////// 群组相关 /////////////////

    /**
     * 创建群组
     *
     * @param groupName 群名
     * @param members   群成员UserName列表
     * @return boolean
     */
    boolean createGroup(String groupName, List<String> members);

    /**
     * 移除群成员
     *
     * @param groupName      群组名称
     * @param memberUserName 成员用户名
     * @return boolean
     */
    boolean removeMember(String groupName, String memberUserName);

    /**
     * 邀请新成员入群
     *
     * @param groupName      群组名称
     * @param memberUserName 成员用户名
     * @return boolean
     */
    boolean inviteMember(String groupName, String memberUserName);

    /**
     * 修改群名称
     *
     * @param groupName    组名称
     * @param newGroupName 新组名称
     * @return boolean
     */
    boolean modifyGroupName(String groupName, String newGroupName);

    /**
     * 获取群组成员列表
     *
     * @param groupName 组名称
     * @return {@link List}<{@link Member}>
     */
    List<Member> getGroupMemberList(String groupName);
}
